package router

import (
	"errors"

	"gitee.com/liukexing/isrn/model"
)

const ()

var ()

func KeySwapCheck(data *model.Trans, key *RemoteCyprto) (*model.KeySwapInfo, error) {
	var packdata []byte
	if key != nil {
		data, err := key.Decrypt(data.Data)
		if err != nil {
			return nil, err
		}
		packdata = data
	} else {
		packdata = data.Data
	}
	swapinfo := &model.KeySwapInfo{}
	if _, err := swapinfo.GetData(packdata); err != nil {
		return nil, err
	}
	//data lengh
	if len(packdata) != data.PackInfo.Lengh {
		return nil, errors.New("Data Length Check Failed")
	}
	//Receiver
	if data.PackInfo.Receiver != nodeid {
		return nil, errors.New("Receiver Check Failed")
	}
	//NodeId and Sender
	if swapinfo.NodeId != data.PackInfo.Sender {
		return nil, errors.New("NodeId and Sender Check Failed")
	}
	pubkey, err := key.UnmarshalPk(swapinfo.Pk)
	if err != nil {
		return nil, err
	}
	//PackInfo Sign
	packinfook, err := pubkey.Verify(packdata, data.PackInfo.Sign)
	if err != nil {
		return nil, err
	}
	if !packinfook {
		return nil, errors.New("PackInfo Sign Check Failed")
	}
	//Trans Sign
	transok, err := pubkey.Verify(data.Data, data.Sign)
	if err != nil {
		return nil, err
	}
	if !transok {
		return nil, errors.New("Trans Sign Check Failed")
	}

	return swapinfo, nil
}

func KeySwapController(data *model.Trans, isEncrypt bool, sender *ConnectInfo) error {
	swapinfo, err := KeySwapCheck(data, getRemoteCyprto(isEncrypt, sender))
	if err != nil {
		sender.Active = false
		return err
	}
	sender.NodeId = swapinfo.NodeId

	pubkey, err := sender.RCyprto.UnmarshalPk(swapinfo.Pk)
	if err != nil {
		return err
	}
	sender.RCyprto.Pk = pubkey

	rpubkey, err := sender.RCyprto.UnmarshalRpk(swapinfo.Rpk)
	if err != nil {
		return err
	}
	sender.RCyprto.Rpk = rpubkey

	sender.Active = true
	if swapinfo.Sign == "Request" {
		return sendSwapResponse(sender)
	}

	return nil
}

func sendSwapRequest(conn *ConnectInfo) error {
	swapInfo, err := conn.RCyprto.BuildSwapInfo("Request")
	if err != nil {
		return err
	}

	data, err := swapInfo.GetByte()
	if err != nil {
		return err
	}
	s, err := conn.RCyprto.Sign(data)
	if err != nil {
		return err
	}

	trans := &model.Trans{}
	trans.CreatPackInfo(data, s, nodeid, conn.NodeId)
	trans.Sign = s
	trans.PackType = model.KeySwap

	msg, err := getTransByte(trans, false, &conn.RCyprto)
	if err != nil {
		return err
	}
	conn.SendMsg(msg)
	return nil
}

func sendSwapResponse(conn *ConnectInfo) error {
	swapInfo, err := conn.RCyprto.BuildSwapInfo("Response")
	if err != nil {
		return err
	}

	data, err := swapInfo.GetByte()
	if err != nil {
		return err
	}

	s, err := conn.RCyprto.Sign(data)
	if err != nil {
		return err
	}
	dataEn, err := conn.RCyprto.Encrypt(data)
	if err != nil {
		return err
	}
	sn, err := conn.RCyprto.Sign(dataEn)
	if err != nil {
		return err
	}
	trans := &model.Trans{}
	trans.CreatPackInfo(dataEn, s, nodeid, conn.NodeId)
	trans.PackInfo.Lengh = len(data)
	trans.Sign = sn
	trans.PackType = model.KeySwap

	msg, err := getTransByte(trans, true, &conn.RCyprto)
	if err != nil {
		return err
	}
	conn.SendMsg(msg)
	return nil
}
